using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OrdersManager.Module;
using OrdersManager.Module.Constants;
using OrdersManager.Module.Services;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using OrderWorkflow;
using System.Workflow.Runtime.Hosting;

namespace OrdersManager.Module.Tests.Services
{
	/// <summary>
	/// Summary description for OrderWorkflowManagerFixture
	/// </summary>
	[TestClass]
	public class OrderWorkflowManagerFixture
	{
		private TestContext testContextInstance;

		public TestContext TestContext
		{
			get 
            { 
                return testContextInstance; 
            }

			set 
            { 
                testContextInstance = value; 
            }

		}

		public OrderWorkflowManagerFixture()
		{
			//
			// TODO: Add constructor logic here
			//
		}

        private IOrderWorkflowManager _orderWorkflowManager;
        private WorkflowRuntime _workflowRuntime;
        private OrderStateMachineDataExchangeService _orderStateMachine;
        private LocalOrderWorkflowMappingCollection _orderWorkflowMapping;

        [TestInitialize()]
		public void MyTestInitialize()
		{
            _workflowRuntime = new WorkflowRuntime("OrderWorkflowRuntimeSection");
            _orderWorkflowMapping = new LocalOrderWorkflowMappingCollection();
            _orderWorkflowManager = new OrderWorkflowManager(_workflowRuntime,_orderWorkflowMapping);

            ExternalDataExchangeService dataService = _workflowRuntime.GetService<ExternalDataExchangeService>();
            _orderStateMachine = (OrderStateMachineDataExchangeService)dataService.GetService(typeof(OrderStateMachineDataExchangeService)); 
		}

        [TestCleanup()]
        public void MyTestCleanup()
        {
            _orderWorkflowManager.Dispose();
            _workflowRuntime = null;
            _orderWorkflowMapping = null;

        }
        private void RunWorkflow(Guid instanceId)
        {
            ManualWorkflowSchedulerService scheduler = _workflowRuntime.GetService<ManualWorkflowSchedulerService>();
            scheduler.RunWorkflow(instanceId);
        }

        private string GetOrderState(Guid orderId)
        {
            Guid instanceId=GetInstanceId(orderId);
            StateMachineWorkflowInstance stateMachine = new StateMachineWorkflowInstance(_workflowRuntime, instanceId);

            return stateMachine.CurrentStateName;
        }
        private Guid GetInstanceId(Guid orderId)
        {
            Guid instanceId;
            if (!_orderWorkflowMapping.TryGetValue(orderId,out instanceId))
                throw new KeyNotFoundException();

            return instanceId;
        }

		[TestMethod]
		public void ShouldAddOrderRemainsInInitialState()
		{
			Guid orderId = Guid.NewGuid();
			RunWorkflow(_orderWorkflowManager.CreateOrderWorkflow(orderId));

            Assert.AreEqual("OrderInitialState", GetOrderState(orderId));
		}

		[TestMethod]
		public void ShouldGetOrderStateInInitialState()
		{
            WorkflowInstance instance;

            // 1 Order in Initial state
            Guid orderIdInitial = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            Assert.AreEqual(OrderStatus.Initial, _orderWorkflowManager.GetOrderState(orderIdInitial));
		}

		[TestMethod,ExpectedException(typeof(KeyNotFoundException))]
		public void ShouldNotNotifyOrderCreatedUnexistingOrder()
		{
			Guid orderId = Guid.NewGuid();
			_orderWorkflowManager.NotifyOrderCreated(orderId);

            Assert.AreEqual("OrderOpenedState", GetOrderState(orderId));
		}

		[TestMethod, ExpectedException(typeof (ArgumentException))]
		public void ShouldNotAddOrderTwice()
		{
			Guid orderId = Guid.NewGuid();

            _orderWorkflowManager.CreateOrderWorkflow(orderId);
			_orderWorkflowManager.CreateOrderWorkflow(orderId);
		}

		[TestMethod]
		public void ShouldChangeStateFromInitialToOpened()
		{
            WorkflowInstance instance;
            Guid orderIdInitial = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            _orderWorkflowManager.NotifyOrderCreated(orderIdInitial);
            RunWorkflow(instance.InstanceId);

            Assert.AreEqual("OrderOpenedState", GetOrderState(orderIdInitial));
		}

		[TestMethod]
		public void ShouldChangeStateFromOpenedToProcessed()
		{
            WorkflowInstance instance;
            Guid orderIdOpened = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderProcessed(orderIdOpened);
            RunWorkflow(instance.InstanceId);

            Assert.AreEqual("OrderProcessedState", GetOrderState(orderIdOpened));
		}

		[TestMethod]
		public void ShouldChangeStateFromProcessedToOpened()
		{
            WorkflowInstance instance;
            Guid orderIdProcessed = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdProcessed, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderUpdated(orderIdProcessed);
            RunWorkflow(instance.InstanceId);

            Assert.AreEqual("OrderOpenedState", GetOrderState(orderIdProcessed));
		}

		[TestMethod]
		public void ShouldChangeStateFromProcessedToShipped()
		{
            WorkflowInstance instance;
            Guid orderIdProcessed = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdProcessed, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderShipped(orderIdProcessed);
            RunWorkflow(instance.InstanceId);

            Assert.AreEqual("OrderShippedState", GetOrderState(orderIdProcessed));
		}

		[TestMethod,ExpectedException(typeof(KeyNotFoundException))]
		public void ShouldChangeStateFromProcessedToCancelled()
		{
            WorkflowInstance instance;
            Guid orderIdProcessed = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdProcessed, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderCancelled(orderIdProcessed);
            RunWorkflow(instance.InstanceId);

			Assert.AreSame(null, _workflowRuntime.GetWorkflow(GetInstanceId(orderIdProcessed)));
		}

		[TestMethod]
		public void ShouldReturnOpenedOrders()
		{
            CreateSampleOrders();

            ICollection<Guid> opened = _orderWorkflowManager.GetOrdersByState(OrderStatus.Opened);

            Assert.AreEqual(3, opened.Count);
		}

		[TestMethod]
		public void ShouldReturnProcessedOrders()
		{
            CreateSampleOrders();
            
            ICollection<Guid> opened = _orderWorkflowManager.GetOrdersByState(OrderStatus.Processed);

            Assert.AreEqual(2, opened.Count);
		}

		[TestMethod]
		public void ShouldReturnShippedOrders()
		{
            CreateSampleOrders();
            
            ICollection<Guid> opened = _orderWorkflowManager.GetOrdersByState(OrderStatus.Shipped);

            Assert.AreEqual(2, opened.Count);
		
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromInitialToProcessed()
		{
            WorkflowInstance instance;
            Guid orderIdInitial = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderWorkflowManager.NotifyOrderProcessed(orderIdInitial);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromInitialToShipped()
		{
            WorkflowInstance instance;
            Guid orderIdInitial = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderShipped(orderIdInitial);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromInitialToCancelled()
		{
            WorkflowInstance instance;
            Guid orderIdInitial = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderCancelled(orderIdInitial);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromOpenedToCancelled()
		{
            WorkflowInstance instance;
            Guid orderIdOpened = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderCancelled(orderIdOpened);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromOpenedToShipped()
		{
            WorkflowInstance instance;
            Guid orderIdOpened = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderShipped(orderIdOpened);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromShippedToOpen()
		{
            WorkflowInstance instance;
            Guid orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderCreated(orderIdShipped);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromShippedToProcessed()
		{
            WorkflowInstance instance;
            Guid orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderProcessed(orderIdShipped);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotChangeStateFromShippedToCancelled()
		{
            WorkflowInstance instance;
            Guid orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderCancelled(orderIdShipped);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotUpdateInitialOrder()
		{
            WorkflowInstance instance;
            Guid orderIdInitial = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderUpdated(orderIdInitial);
        }

        [TestMethod, ExpectedException(typeof(EventDeliveryFailedException))]
		public void ShouldNotUpdateShippedOrder()
		{
            WorkflowInstance instance;
            Guid orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            _orderWorkflowManager.NotifyOrderUpdated(orderIdShipped);
        }

		[TestMethod, ExpectedException(typeof (KeyNotFoundException))]
		public void ShouldNotUpdateCancelledOrder()
		{
            WorkflowInstance instance;
            Guid orderIdCancelled = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderCanceledEvent(orderIdCancelled, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            _orderWorkflowManager.NotifyOrderUpdated(orderIdCancelled);
		}

		[TestMethod]
		public void ShouldReturnPossibleStatesForUnexistingOrder()
		{
			Guid orderId = Guid.NewGuid();
			ICollection<OrderStatus> states = _orderWorkflowManager.GetOrderPossibleStates(orderId);
			Assert.AreEqual(1, states.Count);
			Assert.IsTrue(states.Contains(OrderStatus.Initial));
			Assert.IsFalse(states.Contains(OrderStatus.Opened)); 
			Assert.IsFalse(states.Contains(OrderStatus.Processed));
			Assert.IsFalse(states.Contains(OrderStatus.Shipped));
			Assert.IsFalse(states.Contains(OrderStatus.Cancelled));

		}

		[TestMethod]
		public void ShouldReturnPossibleStatesForInitial()
		{
            WorkflowInstance instance;
            Guid orderIdInitial = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            ICollection<OrderStatus> states = _orderWorkflowManager.GetOrderPossibleStates(orderIdInitial);

            Assert.AreEqual(1, states.Count);
			Assert.IsFalse(states.Contains(OrderStatus.Initial));
			Assert.IsTrue(states.Contains(OrderStatus.Opened)); 
			Assert.IsFalse(states.Contains(OrderStatus.Processed));
			Assert.IsFalse(states.Contains(OrderStatus.Shipped));
			Assert.IsFalse(states.Contains(OrderStatus.Cancelled));
		}

		[TestMethod]
		public void ShouldReturnPossibleStatesForOpened()
		{
            WorkflowInstance instance;
            Guid orderIdOpened = Guid.NewGuid();

            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            ICollection<OrderStatus> states = _orderWorkflowManager.GetOrderPossibleStates(orderIdOpened);

            Assert.AreEqual(2, states.Count);
			Assert.IsFalse(states.Contains(OrderStatus.Initial));
			Assert.IsTrue(states.Contains(OrderStatus.Opened)); 
			Assert.IsTrue(states.Contains(OrderStatus.Processed));
			Assert.IsFalse(states.Contains(OrderStatus.Shipped));
			Assert.IsFalse(states.Contains(OrderStatus.Cancelled));
		}

		[TestMethod]
		public void ShouldReturnPossibleStatesForProcessed()
		{
            WorkflowInstance instance;
            Guid orderIdProcessed = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdProcessed, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            ICollection<OrderStatus> states = _orderWorkflowManager.GetOrderPossibleStates(orderIdProcessed);

            Assert.AreEqual(3, states.Count);
			Assert.IsFalse(states.Contains(OrderStatus.Initial));
			Assert.IsTrue(states.Contains(OrderStatus.Opened));
			Assert.IsFalse(states.Contains(OrderStatus.Processed));
			Assert.IsTrue(states.Contains(OrderStatus.Shipped));
			Assert.IsTrue(states.Contains(OrderStatus.Cancelled));
		
        }

		[TestMethod]
		public void ShouldReturnPossibleStatesForShipped()
		{
            WorkflowInstance instance;
            Guid orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            ICollection<OrderStatus> states = _orderWorkflowManager.GetOrderPossibleStates(orderIdShipped);

            Assert.AreEqual(0, states.Count);
			Assert.IsFalse(states.Contains(OrderStatus.Initial));
			Assert.IsFalse(states.Contains(OrderStatus.Opened));
			Assert.IsFalse(states.Contains(OrderStatus.Processed));
			Assert.IsFalse(states.Contains(OrderStatus.Shipped));
			Assert.IsFalse(states.Contains(OrderStatus.Cancelled));
        }

		[TestMethod]
		public void ShouldReturnPossibleStatesForCancelled()
		{
            WorkflowInstance instance;
            Guid orderIdCancelled = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderCanceledEvent(orderIdCancelled, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            
            ICollection<OrderStatus> states = _orderWorkflowManager.GetOrderPossibleStates(orderIdCancelled);

            Assert.AreEqual(1, states.Count);
			Assert.IsTrue(states.Contains(OrderStatus.Initial));
			Assert.IsFalse(states.Contains(OrderStatus.Opened));
			Assert.IsFalse(states.Contains(OrderStatus.Processed));
			Assert.IsFalse(states.Contains(OrderStatus.Shipped));
			Assert.IsFalse(states.Contains(OrderStatus.Cancelled));
		}

        [TestMethod]
        public void ShouldInstanceStayPending()
        {
            WorkflowInstance instance;
            Guid orderIdOpened = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);

            _orderWorkflowManager.NotifyOrderProcessed(orderIdOpened);

            Assert.IsTrue(_orderWorkflowManager.InstanceIsWaiting(instance.InstanceId));
        }

        private void CreateSampleOrders()
        {
            WorkflowInstance instance;

            // 1 Order in Initial state
            Guid orderIdInitial = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderWorkflowMapping.Add(orderIdInitial, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            //3 Orders in Opened state
            Guid orderIdOpened = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            orderIdOpened = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            orderIdOpened = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdOpened, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdOpened, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            //2 Orders in Processed state
            Guid orderIdProcessed = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdProcessed, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            orderIdProcessed = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdProcessed, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdProcessed, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            //2 Orders in Shipped state
            Guid orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            orderIdShipped = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderShippedEvent(orderIdShipped, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdShipped, instance.InstanceId);
            RunWorkflow(instance.InstanceId);

            //1 Order in Cancelled state
            Guid orderIdCancelled = Guid.NewGuid();
            instance = _workflowRuntime.CreateWorkflow(typeof(OrderStateMachine));
            instance.Start();
            _orderStateMachine.RaiseOrderCreatedEvent(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderProcessedEvent(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
            _orderStateMachine.RaiseOrderCanceledEvent(orderIdCancelled, instance.InstanceId);
            _orderWorkflowMapping.Add(orderIdCancelled, instance.InstanceId);
            RunWorkflow(instance.InstanceId);
        }

	}

}